<?php
/**
 * Created by PhpStorm.
 * User: jaylen
 * Date: 2020-04-09
 * Time: 15:15
 */

namespace app\common\model;


use app\common\exception\ParameterException;
use app\common\exception\TopNodeException;
use app\common\validate\IDCollection;
use app\common\validate\IDMustBeRequire;
use app\common\validate\PaginationParameter;
use think\Model;
use app\common\model\Atlas as AtlasModel;

class BaseModel extends Model
{
    /**
     * 判断分页数据是否正确
     * @param array $params
     */
    public static function validatePaginationData(array $params)
    {
        if (!isset($params['page']) || !isset($params['limit'])) {
            throw new ParameterException([
                'msg' => '分页参数错误'
            ]);
        } else {
            $validate = new PaginationParameter();
            if (!$validate->check($params)) {
                throw new ParameterException([
                    'msg' => $validate->getError()
                ]);
            }
        }
    }

    /**
     * 根据id获取指定字段对应的数据
     * @param int $id 主键id
     * @param array $field 需要查找的字段 ['name','nick_name']
     * @return array
     */
    public static function getDataWithID(int $id, array $field = [])
    {
        $validate = new IDMustBeRequire();
        if (!$validate->check(['id'=>$id])) {
            throw new ParameterException([
                'msg' => $validate->getError(),
            ]);
        }

        $data = static::field($field)->find($id);

        // 判断是否获取到数据
        if (!$data) {
            return [];
        } else {
            return $data->getData();
        }
    }

    /**
     * 根据条件、字段、排序进行查找数据
     * @param array $where 查找条件    ['id','=','1']/[['name','like','tuniao']]/['id'=>1,'name'=>'tuniao']
     * @param array $field 字段条件    ['name','nick_name']
     * @param array $order 排序条件    ['id'=>'desc']
     * @return \think\Collection
     */
    public static function getDataWithField(array $where = [],array $field = [], array $order = []): \think\Collection
    {
        return static::where($where)
            ->field($field)
            ->order($order)
            ->select();
    }

    /**
     * 获取当前父级下所拥有子节点的数量
     * @param int $pid
     * @param string $pid_field
     * @return int
     */
    public static function getChildrenCount(int $pid = 0,string $pid_field = 'pid')
    {
        return static::where([[$pid_field,'=',$pid],['status','=',1]])
            ->count('id');
    }

    /**
     * 根据指定的id更新对应的信息
     * @param $id id值
     * @param $update_data 需要更新的数据
     * @return bool
     */
    public static function updateInfo($id, $update_data)
    {
        $validate = new IDMustBeRequire();
        if (!$validate->check(['id'=>$id])) {
            throw new ParameterException([
                'msg' => $validate->getError(),
            ]);
        }

        $model = static::find($id);

        $result = $model->save($update_data);

        if ($result !== false) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 删除指定id的数据
     * @param $ids
     * @return bool
     */
    public static function delByIDs($ids)
    {
        $validate = new IDCollection();
        if (!$validate->check(['ids'=>$ids])) {
            throw new ParameterException([
                'msg' => $validate->getError()
            ]);
        }

        if (!is_array($ids)) {
            $ids = explode(',',$ids);
        }

        $result = static::destroy($ids);

        if ($result !== false) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 检查当前元素是否有子元素
     * @param $id
     * @param $old_pid
     * @param $new_pid
     * @param string $pid_filed
     */
    public static function checkTopHaveChild($id, $old_pid, $new_pid, $pid_filed = 'pid')
    {
        // 如果为顶级元素或者更换了父级元素
        if ($old_pid != $new_pid) {
            $childCount = static::where($pid_filed,'=', $id)->count('id');
            if (!empty($childCount)) {
                throw new TopNodeException();
            }
        }
    }

    /**
     * 获取富文本下的图片数据
     * @param string $richText
     * @return array
     */
    public static function getRichTextImage(string $richText)
    {
        $img_data = [];
        //使用正则表达式将图片地址提取出来
        preg_match_all('<img.*?src=\"(.*?.*?)\".*?>',$richText,$match_data);
        if (!empty($match_data[1])){
            foreach ($match_data[1] as $key => $value) {
//                $img_data[] = str_replace(WEB_URL.'/upload',"upload",$value);
                $img_data[] = $value;
            }
        }

        return $img_data;
    }

    /**
     * 根据新旧的数据模型，删除指定字段的旧文件
     * @param Model $oldModel
     * @param Model $newModel
     * @param string $imageField
     */
    public static function delDifferentImage(Model $oldModel, Model $newModel, string $imageField)
    {
        $oldImage = $oldModel->getData($imageField);
        $newImage = $newModel->getData($imageField);

        if (empty($oldImage)) {
            return ;
        }

        // 判断旧图片是不是图集里面的，如果是则不进行删除
        $result = AtlasModel::where('img_path','=',$oldImage)->find();
        if (!$result && $oldImage !== $newImage) {
            delFile($oldImage);
        }
    }

    /**
     * 比较两个数组找出就数据中需要删除的文件
     * @param array $oldData
     * @param array $newData
     * @return array
     */
    public static function getDifferentFileWithArray(array $oldData, array $newData): array
    {
        $needDeleteFile = [];

        //遍历旧图片的数据，跟新数据进行比较
        foreach ($oldData as $key => $value) {
            if (!in_array($value,$newData)) {
                $needDeleteFile[] = $value;
            }
        }

        return $needDeleteFile;
    }

    /**
     * 为图片添加域名前缀
     * @param $value
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function prefixImgUrl($value)
    {
        if (empty($value)) {
            return $value;
        }

        return add_image_prefix($value);
    }
}